<?php

namespace app\controller;

use app\BaseController;
use fast\Http;
use fast\Random;
use app\library\Redis;
use think\facade\Cache;

/**
 * 直播监听类
 * */
class LiveListen extends BaseController
{
    /**
     * 开始监听直播间
     * */
    public function start()
    {
        $url = $this->request->param('url');
        if (!$url) {
            $this->error('直播地址不能为空');
        }
        $type = false;
        $room_id = false;
        $extend = [];
        $redis = new Redis(Cache::getStoreConfig('redis'));
        // 根据地址判断直播类型，并获取对应直播间ID
        if(strpos($url,'v.douyin.com') !== false) {
            $type = 'douyin';
            $header = @get_headers($url, true);
            if (!$header) {
                $this->error('链接解析失败');
            }
            $realurl = is_array($header['Location']) ? $header['Location'][0] : $header['Location']; //获取真实链接
            preg_match_all('#(\d+)()?\s*?#s', $realurl, $room_res);
            if(!$room_res || !isset($room_res[0][0])) {
                $this->error('链接提取失败');
            }
            $room_id = $room_res[0][0];
            $signature = \app\library\NodeJs::get_dy_signature($room_id);
            if (!$signature) {
                $this->error('签名提取失败');
            }
            $extend['signature'] = $signature;
        } elseif (strpos($url,'v.kuaishou.com') !== false) {
            $type = 'kuaishou';
            $header = get_headers($url,true);
            if(!$header){
                $this->error('链接解析失败');
            }
            $realurl = is_array($header['Location']) ? $header['Location'][0] : $header['Location']; //获取真实链接
            $str = substr($realurl,strpos($realurl,'?') + 1);
            $arr = explode('&',$str);
            foreach($arr as $k=>$v){
                $tmp = explode('=',$v);
                if(!empty($tmp[0]) && !empty($tmp[1])){
                    $barr[$tmp[0]] = $tmp[1];
                }
            }
            if (!isset($barr['shareObjectId'])) {
                $this->error('链接提取失败');
            }
            $room_id = $barr['shareObjectId'];
            $extend['cursor'] = '';
        } elseif (strpos($url,'v.sph.com') !== false) {
            $type = 'shipinghao';
        }
        if (!$type) {
            $this->error('未解析出对应直播类型');
        }
        if (!$room_id) {
            $this->error('直播间ID获取失败');
        }
        // 生成唯一请求key并存入缓存
        do {
            $key = Random::alnum();
        } while ($redis->has($key));
        $data = [
            'key'       => $key,
            'list_key'  => $key . '-list',
            'room_id'   => $room_id,
            'url'       => $url,
            'type'      => $type,
            'data'      => [],
            'extend'    => $extend,
            'expire'    => 60,
            'timestamp' => time(),
        ];
        $redis->set($key, $data, $data['expire']);
        // 发起异步shell命令
        Http::get(request()->domain() . '/Api/sync_shell?key=' . $key, [], [
            CURLOPT_TIMEOUT         => 1, // 不等待结果
            CURLOPT_CONNECTTIMEOUT  => 0, // 无限等待连接
        ]);
        $this->success('请求成功', [
            'key' => $key,
        ]);
    }

    /**
     * 获取弹幕
     * */
    public function get_comments()
    {
        $key = $this->request->param('key');
        $length = $this->request->param('length', 20);

        $redis = new Redis(Cache::getStoreConfig('redis'));
        $room = $redis->get($key);
        if (!$room) {
            $this->error('key已过期或不存在');
        }
        $redis->expire($key, $room['expire']); // 延长主键过期时间
        $content = $redis->getList($room['list_key'], $length);
        $content = is_array($content) ? $content : [];
        foreach ($content as &$val) {
            $val = json_decode($val, true);
        }
        $this->success('请求成功', [
            'key'       => $room['key'],
            'type'      => $room['type'],
            'content'   => $content,
        ]);
    }

    /**
     * 结束监听
     * */
    public function finish()
    {
        $key = $this->request->param('key');
        $redis = new Redis(Cache::getStoreConfig('redis'));
        $room = $redis->get($key);
        if ($room) {
            $redis->delete($room['key']);
            $redis->delete($room['list_key']);
        }
        $this->success('请求成功');
    }
}